#pragma once
#include <tshark_datatype.h>
#include <tshark_database.h>
#include <ip2regionUtil.h>
#include <processUtil.h>
#include <sqlite3.h>
#include <unordered_map>
#include <mutex>
#include <thread>
#include <string>
#include <vector>
#include <fmt/format.h>

namespace Tshark
{
    enum class WorkStatus
    {
        STATUS_IDLE = 0,      // 空闲
        STATUS_CAPTURING,     // 正在抓包
        STATUS_ANALYSIS_FILE, // 正在分析文件
        STATUS_MONITORING     // 正在监视网卡
    };

    class TsharkManager
    {
    public:
        TsharkManager(const std::string &workDir, const std::string &editcapPath);

        ~TsharkManager();

        inline void setCurrFilePath(const std::string &currFilePath)
        {
            this->currFilePath = currFilePath;
        }

        /// @brief 指定网卡开始抓包
        /// @param 网卡名称
        /// @return
        bool startCapture(const std::string &adapterName);

        /// @brief 停止抓包
        /// @return
        bool stopCapture();

        /// @brief 分析pcap文件，将文件中的packet保存到allPackets中
        /// @param filePath
        /// @return
        error_code analysisFile(const std::string &filePath);

        /// @brief 打印allPackets的数据
        void printAllPackets();

        /// @brief 获取filePath中对应的framNum的16进制数据
        /// @param framNum
        /// @return 如果数据有效，则返回16进制数据
        Result<std::vector<unsigned char>> getPacketHexData(std::uint32_t framNum);

        /// @brief 获取系统所有网卡信息，网卡信息格式：id. name (remark)
        /// @return 系统中所有有效的网卡信息(排除一些特殊网卡)
        Result<std::vector<DataType::AdapterInfo>> getNetworkAdapter();

        /// @brief 开始监视所有网卡流量趋势
        void startMonitorAdaptersFlowTrend();

        /// @brief 停止监视所有网卡流量趋势
        void stopMonitorAdaptersFlowTrend();

        /// @brief 获取所有网卡的数据
        /// @param flowTrendData
        void getAdapterFlowTrendData(std::map<std::string, std::map<long, long>> &flowTrendData);

        /// @brief 获取指定数据包的详情内容
        /// @param frameNumber
        /// @param result
        /// @return
        bool getPacketDetailInfo(uint32_t frameNumber, std::string &result);

        // for test
        bool openDataBase(const std::string &dbName)
        {
            return storage->openDataBase(dbName);
        }

        bool queryPackets(const std::string &ip, uint16_t port, std::vector<std::shared_ptr<DataType::Packet>> &packets);

        bool queryPackets(const QueryConditon &condition, std::vector<std::shared_ptr<DataType::Packet>> &packets);

        /// @brief 获取manager的工作状态
        /// @return
        WorkStatus getWorkStatus()
        {
            std::lock_guard<std::mutex> lock(this->m_workStatusLock);
            return m_workStatus;
        }

        /// @brief 设置manager的工作状态
        /// @param status
        void setWorkStatus(WorkStatus status)
        {
            std::lock_guard<std::mutex> lock(this->m_workStatusLock);
            this->m_workStatus = status;
        }

        /// @brief 将inputFile转换为outputFile的pcap格式
        /// @param inputFile
        /// @param outputFile
        /// @return
        bool convertToPcap(const std::string &inputFile, const std::string &outputFile);

    private:
        /// @brief 将line处理成一个packet数据
        /// @param line
        /// @return packet数据
        Result<DataType::Packet> parseLine(std::string line);

        /// @brief 网卡抓包线程入口函数
        /// @param adapterName 网卡名称
        void captureWorkThreadEntry(const std::string &adapterName);

        /// @brief 监视网卡流量趋势线程入口函数
        /// @param adapterName 需要监视的网卡名称
        void adpterFlowTrendMonitorThreadEntry(const std::string &adapterName);

        /// @brief 存储线程入口
        void storageThreadEntry();

        /// @brief 将packet存入allPackets和packetsTobeStore中
        /// @param packet
        void processPacket(std::shared_ptr<DataType::Packet> packet);

        /// @brief 重置(删除缓存的数据库等)
        void reset();

    private:
        bool stopFlag{true}; // tshark子进程捕获网卡停止标志
        std::mutex captureLock;
        std::shared_ptr<std::thread> captureWorkThread;                                  // 网卡数据捕获线程
        PID_T captureTsharkPid;                                                          // tshark捕获网卡数据子进程pid
        std::string currFilePath;                                                        // pcap文件完整路径
        std::string tsharkPath;                                                          // tshark命令路径（包含tshark）
        std::string editcapPath;                                                         // editcap命令路径（包含editcap）
        std::unordered_map<std::uint32_t, std::shared_ptr<DataType::Packet>> allPackets; // 保存解析完成的packet数据

        // 网卡监视相关变量
    private:
        std::map<std::string, DataType::AdapterMonitorInfo> adapterFlowTrendMonitorMap; // 后台流量趋势监控信息
        std::recursive_mutex adapterFlowTrendMapLock;                                   // 访问流量趋势数据的锁，需要可递归获取的锁(一个线程可能需要重复获取锁)
        long adapterFlowTrendMonitorStartTime = 0;                                      // 网卡流量监控的开始时间

        // 捕捉网卡数据并插入到sqlite数据库
    private:
        std::shared_ptr<TsharkDataBase> storage;
        std::mutex storageLock;
        std::string workDir;
        std::vector<std::shared_ptr<DataType::Packet>> packetsTobeStore;
        std::shared_ptr<std::thread> storageThread;

        // 状态管理
    private:
        WorkStatus m_workStatus;
        std::mutex m_workStatusLock;
    };

};